package physics;

import java.awt.*;
import java.util.*;

import objects.*;

public class PhysXProcessor 
{
	
	boolean hasGravity = true;
	private final Vector gravity = new Vector(0, .098);
	private Toolkit toolkit = Toolkit.getDefaultToolkit();
	private Dimension dim   = toolkit.getScreenSize();
	public PhysXProcessor()
	{
		
	}
	
	public void handleEvents(ArrayList<BasicShape> objects)
	{	

		for (int i = 0; i < objects.size(); i++)
		{
			handleYAxis(objects.get(i));
			handleXAxis(objects.get(i));
		}
		collisions(objects);
		
	}
	
	private void collisions(ArrayList<BasicShape> objects) {
		// TODO Auto-generated method stub
		for (int i = 0; i < objects.size(); i++)
		{
			for (int x = i; x < objects.size(); x++)
			{
				if ((objects.get(i).getPosition().getX() + objects.get(i).getDiameter() > objects.get(x).getPosition().getX() &&
					 objects.get(i).getPosition().getX() + objects.get(i).getDiameter() < objects.get(x).getPosition().getX() + objects.get(x).getDiameter() &&
					 objects.get(i).getPosition().getY() + objects.get(i).getDiameter() > objects.get(x).getPosition().getY() &&
					 objects.get(i).getPosition().getY() + objects.get(i).getDiameter() < objects.get(x).getPosition().getY() + objects.get(x).getDiameter()) 
					 ||
					 (objects.get(x).getPosition().getX() + objects.get(x).getDiameter() > objects.get(i).getPosition().getX() &&
					  objects.get(x).getPosition().getX() + objects.get(x).getDiameter() < objects.get(i).getPosition().getX() + objects.get(i).getDiameter() &&
					  objects.get(x).getPosition().getY() + objects.get(x).getDiameter() > objects.get(i).getPosition().getY() &&
					  objects.get(x).getPosition().getY() + objects.get(x).getDiameter() < objects.get(i).getPosition().getY() + objects.get(i).getDiameter()) 
					  ||
					 (objects.get(i).getPosition().getX() > objects.get(x).getPosition().getX()  + objects.get(x).getDiameter() &&
					  objects.get(i).getPosition().getX() + objects.get(i).getDiameter()  < objects.get(x).getPosition().getX() &&
					  objects.get(i).getPosition().getY() > objects.get(x).getPosition().getY()  + objects.get(x).getDiameter()&&
					  objects.get(i).getPosition().getY()  + objects.get(i).getDiameter()  < objects.get(x).getPosition().getY())
					  ||
					  (objects.get(x).getPosition().getX() > objects.get(i).getPosition().getX()  + objects.get(i).getDiameter() &&
					   objects.get(x).getPosition().getX() + objects.get(x).getDiameter() < objects.get(i).getPosition().getX()&&
					   objects.get(x).getPosition().getY() > objects.get(i).getPosition().getY() + objects.get(i).getDiameter()&&
					   objects.get(x).getPosition().getY() + objects.get(x).getDiameter() < objects.get(i).getPosition().getY()))
				{
					objects.get(i).getVelocity().reverseX();
				//	objects.get(i).getVelocity().multScalarToX(objects.get(i).getCoefRestitution());
					objects.get(x).getVelocity().reverseX();
					//objects.get(x).getVelocity().multScalarToX(objects.get(x).getCoefRestitution());
					applyVelocity(objects.get(i));
					applyVelocity(objects.get(x));
				}
			}
		}
		
	}

	private void handleXAxis(BasicShape object) 
	{
		checkWidthCollision(object);
	}

	private void handleYAxis(BasicShape object)
	{
		if (object.isHasGravity())
			object.setAcceleration(gravity);
		else
		{
			object.setAcceleration(new Vector(object.getAcceleration().getX(), 0));
			object.setVelocity(new Vector(object.getVelocity().getX(), 0));
		}
		
		checkHeightCollision(object);
		applyAcceleration(object);
		applyVelocity(object);
	}
	
	private void checkHeightCollision(BasicShape object) 
	{
		if (object.getPosition().getY() > dim.getHeight() - object.getDiameter() && object.isHasGravity())
			object.setPosition(new Vector(object.getPosition().getX(), dim.getHeight() - object.getDiameter()));
		
		if (object.getPosition().getY() == dim.getHeight() - object.getDiameter() || object.getPosition().getY() == 0)
		{
			object.getVelocity().reverseY();
			object.getVelocity().multScalarToY(object.getCoefRestitution());
			object.getVelocity().multScalarToX(object.getCoefRestitution());
			checkForStationary(object);
		}
	}
	

	private void checkWidthCollision(BasicShape object) 
	{
		if (object.getPosition().getX() < 0 || object.getPosition().getX() > dim.getWidth() - object.getDiameter())
		{
			object.getVelocity().reverseX();
			object.getAcceleration().reverseX();
		}
	}	

	private void checkForStationary(BasicShape object) 
	{
		if (Math.abs(object.getVelocity().getY()) < .5)
		{
			object.setHasGravity(false);
		}
		
		if (Math.abs(object.getVelocity().getX()) < .3)
		{
			object.getAcceleration().setX(0);
			object.getVelocity().setX(0);
		}
	}

	private void applyAcceleration(BasicShape object)
	{
		object.getVelocity().vectorAddition(object.getAcceleration());			                   
	}
	
	private void applyVelocity(BasicShape object)
	{
		object.getPosition().vectorAddition(object.getVelocity());
	}

}
